package com.elastic.dao;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.elastic.domain.Factory;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.geo.GeoPoint;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.MatchAllQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.stereotype.Repository;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;


@Repository
public class GeoSearchDao {

    @Resource
    private RestHighLevelClient client;

    @Resource
    private Factory factory;

    /**查询所有*/
    public List getAll() throws IOException {
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        MatchAllQueryBuilder matchAllQueryBuilder = QueryBuilders.matchAllQuery();
        boolQueryBuilder.should(matchAllQueryBuilder);
        searchSourceBuilder.query(boolQueryBuilder);
        SearchRequest searchRequest = new SearchRequest();
        searchRequest.indices("map_geo");
//        searchRequest.types(cityType);
        searchRequest.source(searchSourceBuilder);
        SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
        List list = new ArrayList();
        for (SearchHit hit: searchResponse.getHits()) {
            String s = JSON.toJSONString(hit);
            JSONObject o = JSON.parseObject(s);
            list.add(o.getJSONObject("sourceAsMap"));
        }
        return list;
    }

    /**
     * 查询多边形中的位置
     * @param points
     * @return
     * @throws Exception
     */
    public List searchGeoPolygon(List<GeoPoint> points) throws Exception {
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder boolQueryBuilder = factory.builtPolygonQuery("locationPoint",points);
        return search(searchSourceBuilder, boolQueryBuilder);
    }

    /**
     * 查询矩形范围内位置
     * @param point1
     * @param point2
     * @return
     * @throws Exception
     */
    public List searchGeoBoundingBox(GeoPoint point1, GeoPoint point2) throws Exception {
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder boolQueryBuilder = factory.builderBoundingBox("locationPoint", point1, point2);
        return search(searchSourceBuilder, boolQueryBuilder);
    }

    /**
     * 查询圆内位置
     * @param distance
     * @param point
     * @return
     * @throws Exception
     */
    public List searchGeoDistance(String distance, GeoPoint point) throws Exception {
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder boolQueryBuilder = factory.builderDistance("locationPoint", distance, point);
        return search(searchSourceBuilder, boolQueryBuilder);
    }

    public List search(SearchSourceBuilder searchSourceBuilder, BoolQueryBuilder boolQueryBuilder) throws Exception {
        searchSourceBuilder.query(boolQueryBuilder);
        SearchRequest searchRequest = new SearchRequest();
        searchRequest.indices("map_geo");
//        searchRequest.types(cityType);
        searchRequest.source(searchSourceBuilder);
        SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
        List list = new ArrayList();
        for (SearchHit hit: searchResponse.getHits()) {
            String s = JSON.toJSONString(hit);
            System.out.println(s);
            JSONObject o = JSON.parseObject(s);
            list.add(o.getJSONObject("sourceAsMap"));
        }
        return list;
    }


}